#ifndef  _BANDWITH_H_
#define  _BANDWITH_H_

#include "../define/define.h"
#include "../util/lock.h"

#define max_date 11

struct bw_data 
{
	float  bytes;
	uint32 tick;
};

class  band_with
{
public:
     band_with()
	 {
		 func_lock locker;
		 reset();
	 }

	 void add_bytes(float bytes,uint32 tick)
	 {
		 func_lock locker;
		 m_data[m_pos].bytes = bytes;
		 m_data[m_pos].tick  = tick;
         m_pos++;
		 
		 if(m_pos >= max_date)
			 m_pos = 0;
	     
		 test(tick);
	 }

	 void test(uint32 tick)
	 {
		 func_lock locker;
		 if(tick - m_last_tick > 5 * 1000)
		 {
			 float value = 0.0f;
			 float bandwith = m_band_with;
			 
			 for(int i=0;i<max_date;i++)
			 {
				 value += m_data[i].bytes;
			 }

			 value = value / 10.0f;

			 if(value > bandwith * 0.9f)
				 bandwith = bandwith + (value - bandwith) * 1.3f;

			 if(value < bandwith * 0.75f)
				 bandwith = bandwith + (bandwith -value) * 3.0f;
             
			 if(m_band_with > bandwith)
				 m_band_with = m_band_with * 0.7f + bandwith + 0.3f;

			 if(m_band_with < bandwith)
                 m_band_with = m_band_with * 0.3f + bandwith + 0.7f;
		     
			 m_band_with = max(m_band_with,20.0f);
			 m_last_tick = tick;
		 }
	 }

	 void reset()
	 {
		 func_lock locker;
		 m_pos = 0;
		 m_last_tick = 0;
		 m_band_with = 20.0f;

		 memset(m_data,0,sizeof(bw_data) * max_date);
	 }

	 float get_band_with()
	 {
		 func_lock locker;
		 return m_band_with;
	 }

private:
     
	uint32 m_pos;
	uint32 m_last_tick;
	
	float     m_band_with;
	bw_data   m_data[max_date];
};
#endif